package me.baicai.weixin.utils;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.xml.XmlMapper;
import me.baicai.weixin.conf.WeiXinKey;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StringUtils;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;


public class WeiXinUtils
{

    public static String JsonToXml(JSONObject jsonObject)
    {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = jsonObject.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext())
        {
            Map.Entry entry = (Map.Entry)it.next();
            sb.append("<" + entry.getKey() + ">" + entry.getValue() + "</" + entry.getKey() + ">");
        }
        sb.append("</xml>");
        return sb.toString();
    }

    public static String MapToXml(Map<String,String> parameters) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            sb.append("<" + entry.getKey() + ">" + entry.getValue() + "</" + entry.getKey() + ">");
        }
        sb.append("</xml>");
        return sb.toString();
    }

    public static String MD5(SortedMap<String, String> jsonObject)
    {
        StringBuffer sb = new StringBuffer();
        for(Map.Entry<String,String> entry: jsonObject.entrySet()){
            if (!StringUtils.isEmpty(entry.getValue()))
                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        String str=sb.toString();
        sb.append("key=" + WeiXinKey.passwd);
        return toMd5(sb.toString()).toUpperCase();
    }

    public static String toMd5(String text)
    {
        try
        {
            return toMd5(text.getBytes("utf-8"));
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public static String toMd5(byte[] text)
    {
        try
        {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(text);
            return toHex(bytes).toLowerCase();
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    private static String toHex(byte[] bytes)
    {
        final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
        StringBuilder ret = new StringBuilder(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++)
        {
            ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
            ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
        }
        return ret.toString();
    }


    public static JSONObject convertXmlIntoJSONObject (String xml)
    {
        XmlMapper xmlMapper = new XmlMapper();
        JSONObject param = null;
        try
        {
            param = xmlMapper.readValue(xml, JSONObject.class);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        return param;
    }


    public static String callWeiXin(String data, String url) throws Exception {

        /**
         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
         */
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        //这里自行实现我是使用数据库配置将证书上传到了服务器可以使用 FileInputStream读取本地文件
        BufferedInputStream inputStream = FileUtil.getInputStream(WeiXinKey.keyStore);
        try {
            //这里写密码..默认是你的MCHID
            keyStore.load(inputStream, WeiXinKey.mchid.toCharArray());
        } finally {
            inputStream.close();
        }
        SSLContext sslcontext = SSLContexts.custom()
            //这里也是写密码的
            .loadKeyMaterial(keyStore, WeiXinKey.mchid.toCharArray())
            .build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
            sslcontext,
            SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLSocketFactory(sslsf)
            .build();
        try {
            HttpPost httpost = new HttpPost(url);
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                //接受到返回信息
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
                return jsonStr;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }



}

